﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetJavap.AttributeInfos
{
    public class CodeAttributeInfo : AttributeInfo, IWithAttributeMember
    {
        private UInt16 _maxStack;
        private UInt16 _maxLocals;
        private UInt32 _codeLength;
        private Byte[] _code;
        private UInt16 _exceptionTableLength;
        private ExceptionInfo[] _exceptionTable;
        private UInt16 _attributesCount;
        private AttributeInfo[] _attributes;

        private Dictionary<UInt32, JOpcode> _opcodes;

        public UInt16 MaxStack { get { return this._maxStack; } }
        public UInt16 MaxLocals { get { return this._maxLocals; } }
        public Byte[] ByteCode { get { return this._code; } }
        public Dictionary<UInt32,JOpcode> Opcodes
        {
            get
            {
                if (this._opcodes == null)
                {
                    this._opcodes = ArrayBuilder.BuildOpCodes(this._code, this.ParentClass);
                }
                return this._opcodes;
            }
        }
        public ExceptionInfo[] ExceptionTable { get { return this._exceptionTable; } }
        public AttributeInfo[] Attributes { get { return this._attributes; } }

        public CodeAttributeInfo(BinaryReader reader, JavaClass cls,ClassMember defineMember)
            : base(reader, cls,defineMember)
        {
            this._maxStack = reader.ReadUInt16BE();
            this._maxLocals = reader.ReadUInt16BE();
            this._codeLength = reader.ReadUInt32BE();
            this._code = reader.ReadBytesRequired(this._codeLength);
            this._exceptionTableLength = reader.ReadUInt16BE();
            this._exceptionTable = ArrayBuilder.BuildArray(() => new ExceptionInfo(reader, cls), this._exceptionTableLength);
            this._attributesCount = reader.ReadUInt16BE();
            this._attributes = ArrayBuilder.BuildAttributes(reader, this.ParentClass, this._attributesCount);
        }
    }
}
